<template>
  <div>
    <div style="border: #efefef solid 1px; height: 100vh;width: 100%;">
      <!-- 关系图组件，绑定右键事件（接收组件传递的node参数） -->
      <relation-graph ref="graphRef$" :options="options" @contextmenu="handleRightClick">
        <template #node="{ node }">
          <div style="width: 150px;height: 200px;background-color: #3783c0" class="graph-node-container"
            :data-node="JSON.stringify(node)">
            <!-- 节点标题（支持重命名时的输入框切换） -->
            <div v-if="!editingNodeId || editingNodeId !== node.id">
              {{ node.text }}
            </div>
            <el-input v-else v-model="editingNodeText" class="node-edit-input" @blur="confirmRename(node.id)"
              @keyup.enter="confirmRename(node.id)" @keyup.esc="cancelRename" ref="editInputRef" />
            <table class="c-data-table">
              <tr>
                <th>名称</th>
                <th>类型</th>
              </tr>
              <template v-for="column of node.data.columns" :key="column.columnName">
                <tr>
                  <td>
                    <div :id="`${node.id}-${column.columnName}`">{{ column.columnName }}</div>
                  </td>
                  <td>{{ column.dataType }}</td>
                </tr>
              </template>
            </table>
          </div>
        </template>
      </relation-graph>
    </div>

    <!-- 1. 节点右键菜单（设计表/重命名/删除表） -->
    <div v-if="showNodeContextMenu" :style="nodeContextMenuStyle" class="context-menu" @click.stop>
      <div class="menu-item" @click="handleDesignTable">设计表</div>
      <div class="menu-item" @click="handleRenameNode">重命名</div>
      <div class="menu-item" @click="handleDeleteNode" style="color: #ff4d4f;">删除表</div>
    </div>

    <!-- 2. 空白处右键菜单（保留原有功能） -->
    <div v-if="showBlankContextMenu" :style="blankContextMenuStyle" class="context-menu" @click.stop>
      <div class="menu-item" @click="addNode">添加节点</div>
      <div class="menu-item" @click="clearGraph">清空图表</div>
      <div class="menu-item" @click="downloadGraph">下载图表</div>
    </div>

    <!-- 设计表弹窗（示例：可扩展为表单） -->
    <el-dialog title="设计表结构" v-model="showDesignDialog" width="50%">
      <template #default>
        <h4>当前表：{{ currentNode?.text }}</h4>
        <el-tabs v-model="activeName" type="card">
          <el-tab-pane label="字段" name="字段">
            
          </el-tab-pane>
          <el-tab-pane label="外键" name="外键">外键</el-tab-pane>
        </el-tabs>
   
      </template>
      <template #footer>
        <el-button @click="showDesignDialog = false">取消</el-button>
        <el-button type="primary" @click="saveTableDesign">保存</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref, nextTick } from 'vue'
import RelationGraph from 'relation-graph-vue3'
import type { RelationGraphComponent, RGJsonData, RGNode } from 'relation-graph-vue3'
// 1. 关系图核心实例与数据
const graphRef$ = ref<RelationGraphComponent | null>(null)
const graphData = ref<RGJsonData>({
  rootId: 'root',
  nodes: [],
  lines: []
})
const options = {
  defaultExpandHolderPosition: 'right',
  allowNodeDrag: true,
  allowShowDownloadButton: false,
  layout: { layoutName: 'fixed' }
}


const activeName = ref('字段')


// 2. 右键菜单状态（区分节点右键/空白右键）
const showNodeContextMenu = ref(false) // 节点右键菜单显示状态
const showBlankContextMenu = ref(false) // 空白处右键菜单显示状态
const nodeContextMenuStyle = ref({ left: '0px', top: '0px', position: 'fixed', zIndex: 1000 })
const blankContextMenuStyle = ref({ left: '0px', top: '0px', position: 'fixed', zIndex: 1000 })
const currentNode = ref<RGNode | null>(null) // 当前右键点击的节点

// 3. 重命名相关状态
const editingNodeId = ref<string | null>(null) // 正在编辑的节点ID
const editingNodeText = ref('') // 编辑中的节点文本
const editInputRef = ref<HTMLInputElement | null>(null) // 重命名输入框引用

// 4. 设计表弹窗相关状态
const showDesignDialog = ref(true)
const tableForm = ref({
  tableName: '', // 表名
  fields: [] // 字段列表（默认1个空字段）
})

// 初始化图表
onMounted(() => {
  graphRef$.value?.setJsonData(graphData.value)
})

/**
 * 处理右键点击事件：区分节点右键 vs 空白右键
 */
const handleRightClick = (event: MouseEvent, node?: RGNode) => {
  // 阻止浏览器默认右键菜单
  event.preventDefault()
  event.stopPropagation()
  // 先关闭所有已显示的菜单
  closeAllContextMenu()
  // 情况1：点击的是节点（通过事件目标是否包含节点容器类名判断）
  const isClickNode = event.target instanceof HTMLElement &&
    event.target.closest('.graph-node-container')

  if (isClickNode && node) {
    currentNode.value = JSON.parse(isClickNode.getAttribute("data-node")!) // 记录当前点击的节点
    showNodeContextMenu.value = true
    // 菜单定位到鼠标位置
    nodeContextMenuStyle.value = {
      ...nodeContextMenuStyle.value,
      left: `${event.clientX}px`,
      top: `${event.clientY}px`
    }
  }
  // 情况2：点击的是空白处
  else {
    showBlankContextMenu.value = true
    blankContextMenuStyle.value = {
      ...blankContextMenuStyle.value,
      left: `${event.clientX}px`,
      top: `${event.clientY}px`
    }
  }

  // 点击其他地方关闭所有菜单
  const closeMenu = () => {
    closeAllContextMenu()
    document.removeEventListener('click', closeMenu)
  }
  setTimeout(() => document.addEventListener('click', closeMenu), 0)
}

/**
 * 关闭所有右键菜单
 */
const closeAllContextMenu = () => {
  showNodeContextMenu.value = false
  showBlankContextMenu.value = false
}

// ------------------------------
// 节点右键菜单：核心功能实现
// ------------------------------

/**
 * 1. 设计表：打开弹窗并加载当前节点的表结构
 */
const handleDesignTable = () => {
  if (!currentNode.value) return
  const node = currentNode.value
  console.log('handleDesignTable', node)
  // 加载当前节点的表数据到表单
  tableForm.value.tableName = node.text
  tableForm.value.fields = node.data.columns.length
    ? [...node.data.columns]
    : []
  console.log('tableForm', tableForm.value)

  // 显示设计表弹窗
  showDesignDialog.value = true
  closeAllContextMenu()
}

/**
 * 保存表设计（更新节点数据）
 */
const saveTableDesign = () => {
  if (!currentNode.value) return
  const nodeIndex = graphData.value.nodes.findIndex(n => n.id === currentNode.value!.id)

  if (nodeIndex > -1) {
    // 1. 更新节点文本（表名）
    graphData.value.nodes[nodeIndex].text = tableForm.value.tableName
    // 2. 更新节点字段数据（过滤空字段）
    graphData.value.nodes[nodeIndex].data.columns = tableForm.value.fields
      .filter(field => field.columnName.trim()) // 移除空字段
      .map(field => ({ ...field })) // 深拷贝避免引用问题

    // 刷新图表
    graphRef$.value?.setJsonData(graphData.value)
    // 关闭弹窗
    showDesignDialog.value = false
  }
}

/**
 * 设计表：新增字段
 */
const addField = () => {
  tableForm.value.fields.push({ columnName: '', dataType: 'VARCHAR' })
}

/**
 * 设计表：删除字段
 */
const removeField = (idx: number) => {
  tableForm.value.fields.splice(idx, 1)
}

/**
 * 2. 重命名节点：显示输入框并聚焦
 */
const handleRenameNode = () => {
  if (!currentNode.value) return
  const node = currentNode.value
  console.log('handleRenameNode', node)

  // 记录编辑状态
  editingNodeId.value = node.id
  editingNodeText.value = node.text // 初始值为当前节点文本

  // 等待输入框渲染后聚焦
  nextTick(() => {
    editInputRef.value?.focus()
  })

  closeAllContextMenu()
}

/**
 * 确认重命名（失去焦点或按Enter）
 */
const confirmRename = (nodeId: string) => {
  const nodeIndex = graphData.value.nodes.findIndex(n => n.id === nodeId)
  if (nodeIndex > -1 && editingNodeText.value.trim()) {
    // 更新节点文本
    graphData.value.nodes[nodeIndex].text = editingNodeText.value.trim()
    graphRef$.value?.setJsonData(graphData.value)
  }
  // 取消编辑状态
  editingNodeId.value = null
}

/**
 * 取消重命名（按Esc）
 */
const cancelRename = () => {
  editingNodeId.value = null
}

/**
 * 3. 删除表：移除节点及关联线条
 */
const handleDeleteNode = () => {
  if (!currentNode.value || !confirm('确定要删除该表吗？')) return
  const nodeId = currentNode.value.id

  // 1. 删除节点
  graphData.value.nodes = graphData.value.nodes.filter(n => n.id !== nodeId)
  // 2. 删除与该节点相关的所有线条（避免残留无效线条）
  graphData.value.lines = graphData.value.lines.filter(
    line => line.from !== nodeId && line.to !== nodeId
  )

  // 刷新图表
  graphRef$.value?.setJsonData(graphData.value)
  closeAllContextMenu()
  currentNode.value = null // 清空当前节点记录
}

const count = ref(0)
// ------------------------------
// 原有空白处菜单功能（保留）
// ------------------------------
const addNode = () => {
  if (!graphRef$.value) return
  const newNodeId = `node_${Date.now()}`
  graphData.value.nodes.push({
    id: newNodeId,
    text: `table_${count.value++}`,
    x: parseInt(blankContextMenuStyle.value.left) + 20,
    y: parseInt(blankContextMenuStyle.value.top) + 20,
    color: '#3783c0',
    nodeShape: 1,
    data: { columns: [] } // 初始无字段
  })

  graphRef$.value.setJsonData(graphData.value)
  closeAllContextMenu()
}

const clearGraph = () => {
  if (!graphRef$.value || !confirm('确定要清空图表吗？')) return
  graphData.value.nodes = []
  graphData.value.lines = []
  graphRef$.value.setJsonData(graphData.value)
  closeAllContextMenu()
}

const downloadGraph = () => {
  graphRef$.value?.downloadGraph()
  closeAllContextMenu()
}
</script>

<style scoped lang="scss">
// 关系图基础样式
::v-deep(.relation-graph) {
  .rel-map {
    background-size: 30px 30px;
    background-image:
      linear-gradient(90deg, rgba(0, 0, 0, .1) 1px, transparent 0),
      linear-gradient(180deg, rgba(0, 0, 0, .1) 1px, transparent 0);
  }
}

// 右键菜单通用样式
.context-menu {
  width: 120px;
  background: white;
  border-radius: 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
  border: 1px solid #e0e0e0;
  padding: 5px 0;

  .menu-item {
    padding: 8px 15px;
    font-size: 14px;
    cursor: pointer;
    transition: background 0.2s;

    &:hover {
      background-color: #f5f5f5;
      color: #1890ff;
    }
  }
}

// 节点表格样式
.c-data-table {
  background-color: #ffffff;
  border-collapse: collapse;
  width: 100%;
  margin-top: 10px;

  td,
  th {
    border: 1px solid #3783c0;
    color: #333333;
    padding: 5px;
    text-align: center;
  }

  td div {
    background-color: #1da9f5;
    color: #ffffff;
    border-radius: 5px;
    padding: 2px 0;
  }
}

// 节点重命名输入框样式
.node-edit-input {
  width: 100%;
  padding: 4px 8px;
  border: 1px solid #1da9f5;
  border-radius: 4px;
  outline: none;
  font-size: 14px;
}

// 设计表弹窗样式
.design-form {
  .field-item {
    display: flex;
    align-items: center;
    margin-bottom: 10px;

    &:last-child {
      margin-bottom: 0;
    }
  }
}

// 防止Element Plus样式穿透问题（如需）
::v-deep(.el-dialog__body) {
  padding: 20px;
}

::v-deep(.el-form-item) {
  margin-bottom: 16px;
}
</style>